package de.breitbeil.jbooking.command;

import java.io.IOException;
import java.util.Locale;

import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JLabel;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;
import org.springframework.binding.form.FormModel;
import org.springframework.context.ApplicationContext;
import org.springframework.richclient.application.Application;
import org.springframework.richclient.command.ActionCommand;
import org.springframework.richclient.image.ImageSource;

public class ConnectionTestCommand extends ActionCommand {

    public static final String ID = "connectionTestCommand";

    protected static Log logger = LogFactory.getLog(ConnectionTestCommand.class);
    
    private FormModel formModel;
    private JLabel label;
    private Icon successIcon;
    private Icon failedIcon;

    public ConnectionTestCommand(FormModel formModel, JLabel label) {
        super(ID);
        this.formModel = formModel;
        this.label = label;
        successIcon = getIcon(ID+".connectionSuccess.icon");
        failedIcon = getIcon(ID+".connectionFailed.icon");
    }

    @Override
    protected void doExecuteCommand() {
        String host = (String) formModel.getValueModel("host").getValue();
        int port = (Integer) formModel.getValueModel("port").getValue();
        String username = (String) formModel.getValueModel("username").getValue();
        String password = (String) formModel.getValueModel("password").getValue();

        FTPClient ftpClient = new FTPClient();

        label.setText(getMessage(ID+".connectingTo.label", new Object[]{host, port}));
        try {
            // Test Connection
            ftpClient.setDefaultPort(port);
            ftpClient.connect(host);
            int reply = ftpClient.getReplyCode();
            if(!FTPReply.isPositiveCompletion(reply)) {
                ftpClient.disconnect();
                label.setText(getMessage(ID+".connectionRefused.label", new Object[]{reply}));
                label.setIcon(failedIcon);
                return;
            }

            // Test User/Password
            ftpClient.login(username, password);
            reply = ftpClient.getReplyCode();
            if(!FTPReply.isPositiveCompletion(reply)) {
                ftpClient.disconnect();
                label.setText(getMessage(ID+".connectionAuthFailed.label", new Object[]{reply}));
                label.setIcon(failedIcon);
                return;                
            }

            // Disconnect
            ftpClient.disconnect();
            label.setText(getMessage(ID+".connectionSuccess.label"));
            label.setIcon(successIcon);

        } catch (Exception e) {
            label.setText(getMessage(ID+".connectingToFailed.label", new Object[]{host, port}));
            label.setIcon(failedIcon);
            logger.warn("Connecting to FTP Server failed", e);

        } finally {
            if(ftpClient.isConnected()) {
                try {
                    ftpClient.disconnect();
                } catch(IOException ignore) {}
            }
        }
    }

    protected Icon getIcon(String code) {
        ApplicationContext context = Application.instance().getApplicationContext();
        ImageSource imageSource = (ImageSource)context.getBean("imageSource");
        Icon icon = new ImageIcon(imageSource.getImage(code), "");
        return icon;
    }
    
    protected String getMessage(String code) {
        ApplicationContext context = Application.instance().getApplicationContext();
        return context.getMessage(code, new Object[0], Locale.getDefault());
    }

    protected String getMessage(String code, Object arg) {
        ApplicationContext context = Application.instance().getApplicationContext();
        return context.getMessage(code, new Object[]{ arg }, Locale.getDefault());
    }

    protected String getMessage(String code, Object[] args) {
        ApplicationContext context = Application.instance().getApplicationContext();
        return context.getMessage(code, args, Locale.getDefault());
    }
}
